/**
 * Copyright (c) 2012-2014, Yang Yang <cntototo@gmail.com>
 *
 * This software may be distributed under the terms of the New BSD License.
 * See README for more details.
 */

#include "dispatcher.h"

#define LOG_TAG "DISPATCHER"

#include "include.h"
#include "global.h"
#include "def.h"
#include "util.h"
#include "log.h"

#include "func_generic.h"
#include "func_sta.h"


/***********************************************************
 *                     Global functions
 ***********************************************************
 */

enum wfs_internal_err wfs_dispatch(struct wfs_cmd *cmd,
		struct wfs_iface *cur_if, char **resp, int *resp_len)
{
	enum wfs_internal_err ret = WFS_INTERNAL_ERR_SUCCESS;
	u32 max_len = 0;

	assert(cmd && cur_if && resp && resp_len);

	ENTER();

	wfs_printf(LOG_DEBUG, "WFS receives command: %s", cmd->cmd);

	*resp_len = 0;
	*resp = (char *) zalloc(BUF_LEN);
	if (!*resp) {
		ret = WFS_INTERNAL_ERR_OOM;
		goto out;
	}
	max_len = BUF_LEN;

	/** Commands to func_generic */
	if (IS_CMD(cmd->cmd, STATUS) || IS_CMD(cmd->cmd, USE_DRIVER)) {
		ret = func_generic_command(cmd, cur_if, resp, resp_len,
					max_len);
		goto out;
	}
	/** Commands to func_sta */
	if (IS_CMD(cmd->cmd, ASSOCIATE) || IS_CMD(cmd->cmd, SCAN) ||
			IS_CMD(cmd->cmd, SCAN_RESULTS)) {
		ret = func_sta_command(cmd, cur_if, resp, resp_len, max_len);
		goto out;
	}

	/** TODO: commands to other functionalities */

out:
	if (*resp_len == 0) {
		FREE(*resp);
		if (ret == WFS_INTERNAL_ERR_SUCCESS) {
			*resp = build_ok_resp();
			if (!*resp)
				ret = WFS_INTERNAL_ERR_OOM;
			else
				*resp_len = strlen(OK_STR) + 1;
		} else {
			*resp = build_fail_resp();
			if (!*resp)
				ret = WFS_INTERNAL_ERR_OOM;
			else
				*resp_len = strlen(FAIL_STR) + 1;
		}
	}

	LEAVE();
	return ret;
}
